// See https://github.com/qtproject/qttools/blob/dev/src/designer/src/
// - lib/sdk/abstractpropertyeditor.h
// - lib/shared/qdesigner_propertyeditor_p.h
// - components/propertyeditor/propertyeditor.h

#include "itempropertyeditor.h"
#include "propertybrowser.h"
#include "propertymanager.h"

#include "xdl/symbol.h"

#include "command/setpropertycommand.h"

#include <QVBoxLayout>

namespace SymbolEditor
{

    ItemPropertyEditor::ItemPropertyEditor(QWidget *parent):
        QWidget(parent), m_item(nullptr)
    {
        setLayout(new QVBoxLayout);

        // TODO: setBrowser();
        //m_browser = new QtGroupBoxPropertyBrowser;
        //m_browser = new QtButtonPropertyBrowser;
        m_browser = new TreePropertyBrowser();
        layout()->addWidget(m_browser);
        layout()->setMargin(0);

        // TODO: setManager();
        m_manager = new PropertyManager(this);
        m_manager->setBrowserFactories(m_browser);

        connect(m_manager, &PropertyManager::propertyAdded,
                m_browser, &QtAbstractPropertyBrowser::addProperty);

        connect(m_manager, &PropertyManager::valueChanged,
                this, &ItemPropertyEditor::onValueChanged);

    }

    ItemPropertyEditor::~ItemPropertyEditor()
    {

    }

    const Item *ItemPropertyEditor::item() const
    {
        return m_item;
    }

    void ItemPropertyEditor::setPalette(LeGraphicsView::Palette palette)
    {
        m_palette = palette;
        m_manager->setPalette(m_palette);
    }

    LeGraphicsView::Palette ItemPropertyEditor::palette() const
    {
        return m_palette;
    }

    void ItemPropertyEditor::onValueChanged(quint64 id, const QVariant &value)
    {
        if (m_updatingProperties)
        {
            return;
        }

        auto command = new SetPropertyCommand();
        command->setItemId(m_item->id());
        command->setPropertId(PropertyId(id));
        command->setPropertyValue(value);
        emit commandRequested(command);
    }

    // FIXME: One day we'll have to support editing (common) properties of several items
    void ItemPropertyEditor::setItems(QList<const Item *> items)
    {
        if (items.count() == 0)
        {
            setItem(nullptr);
        }
        else
        {
            setItem(items.first());
        }
    }

    void ItemPropertyEditor::setItem(const Item *item)
    {
        if (m_item == item)
        {
            return;
        }

        clear();
        m_item = item;
        load();
    }

    void ItemPropertyEditor::updateProperty(quint64 id, const QVariant &value)
    {
        m_updatingProperties = true;
        m_manager->setValue(id, value);
        m_updatingProperties = false;
    }

    void ItemPropertyEditor::clear()
    {
        m_browser->clear();
        m_manager->clear();
    }

    void ItemPropertyEditor::load()
    {
        if (m_item == nullptr)
        {
            return;
        }

        m_updatingProperties = true;

        for (auto id : m_item->propertyIdList())
        {
            switch (id)
            {
                case PositionProperty:
                    addCoordinate(id);
                    break;
                case WidthProperty:
                case HeightProperty:
                case RadiusProperty:
                case XRadiusProperty:
                case YRadiusProperty:
                    addLength(id);
                    break;
                case OpacityProperty:
                    addPercentage(id);
                    break;
                case RotationProperty:
                case StartAngleProperty:
                case SpanAngleProperty:
                    addAngle(id);
                    break;
                case LockedProperty:
                case VisibilityProperty:
                case XMirroredProperty:
                case YMirroredProperty:
                    addBistate(id);
                    break;
                case LineStyleProperty:
                    addLineStyle(id);
                    break;
                case LineWidthProperty:
                    addLineWidth(id);
                    break;
                case FillStyleProperty:
                    addFillStyle(id);
                    break;
                case LineColorProperty:
                case TextColorProperty:
                case FillColorProperty:
                    addColor(id);
                    break;
                case VerticesProperty:
                case TextProperty:
                case FontFamilyProperty:
                case FontSizeProperty:
                    // Not supported
                    break;
            }
        }

        m_updatingProperties = false;
    }

    void ItemPropertyEditor::addCoordinate(quint64 id)
    {
        m_manager->addCoordinate(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addLength(quint64 id)
    {
        m_manager->addLength(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addAngle(quint64 id)
    {
        m_manager->addAngle(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addPercentage(quint64 id)
    {
        m_manager->addPercentage(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addColor(quint64 id)
    {
        m_manager->addColor(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addBistate(quint64 id)
    {
        m_manager->addBistate(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addText(quint64 id)
    {
        m_manager->addText(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addLineStyle(quint64 id)
    {
        m_manager->addLineStyle(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addLineWidth(quint64 id)
    {
        m_manager->addLineWidth(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

    void ItemPropertyEditor::addFillStyle(quint64 id)
    {
        m_manager->addFillStyle(id, m_item->friendlyPropertyName(id));
        m_manager->setValue(id, m_item->property(id));
    }

}
